﻿using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using Microsoft.Interop.Security.AzRoles;

namespace Authorization
{

    [DataContract(Name = "RoleDefinition", Namespace = "http://authorizationservices/v1")]
    public class RoleDefinition
    {
        private readonly IAzRoleDefinition _azRoleDefinition;

        #region Properties

        public Application Application { get; internal set; }

        [DataMember(Name = "Description", IsRequired = false)]
        public string Description { get; set; }

        [DataMember(Name = "Name", IsRequired = true)]
        public string Name { get; set; }

        [DataMember(Name = "Definition", IsRequired = false)]
        public Definition Definition { get; internal set; }
        /// <summary>
        ///  Name do <see cref="Scope"/> definido nesse <see cref="Role"/>
        /// </summary>
        [DataMember(Name = "ScopeName", IsRequired = false)]
        public string ScopeName
        {
            get;
            set;
        }

        #endregion

        internal RoleDefinition(Application application, IAzRoleDefinition azmanRoleDefinition, string scopeName)
        {
            this.Application = application;
            this.Description = azmanRoleDefinition.Description;
            this.Name = azmanRoleDefinition.Name;
            this._azRoleDefinition = azmanRoleDefinition;
            this.ScopeName = scopeName;
            Definition = scopeName != null ? Definition.Scope : Definition.Application;
        }

        ~RoleDefinition()
	    {
            if (_azRoleDefinition != null)
                Marshal.FinalReleaseComObject(_azRoleDefinition);
        }

        public void RemoveRoleDefinition(string childRoleDefinitionName)
        {
            this._azRoleDefinition.DeleteRoleDefinition(childRoleDefinitionName);
        }

        public void AddRoleDefinition(string childRoleDefinitionName)
        {
            this._azRoleDefinition.AddRoleDefinition(childRoleDefinitionName);
        }
            
        public RoleAssignmentCollection GetRoleAssignments(string scopeNameToSearch, bool isRecursive)
        {
            return new RoleAssignmentCollection(this.Application, this._azRoleDefinition.RoleAssignments(scopeNameToSearch,isRecursive));
        }

        public string[] GetTaskNames()
        {
            var tasks = this._azRoleDefinition.Tasks as object[];

            if (tasks == null) return null;

            var taskNames = new List<string>(tasks.Length);

            foreach (var o in tasks)
            {
                taskNames.Add((string)o);
            }

            return taskNames.ToArray();
        }

        public string[] GetOperationNames()
        {
            var operations = this._azRoleDefinition.Operations as object[];

            if (operations == null) return null;

            var operationNames = new List<string>(operations.Length);

            foreach (var o in operations)
            {
                operationNames.Add((string)o);
            }

            return operationNames.ToArray();
        }

        public string[] GetRoleDefinitionNames()
        {
            var roleDefinitions = this._azRoleDefinition.RoleDefinitions;

            if (roleDefinitions == null) return null;

            var roleNames = new List<string>(roleDefinitions.Count);

            foreach (IAzRoleDefinition roleDefinition in roleDefinitions)
            {
                roleNames.Add(roleDefinition.Name);
            }

            return roleNames.ToArray();
        }

        public  RoleDefinitionCollection GetRoleDefinitions()
        {
            return new RoleDefinitionCollection(this.Application, this._azRoleDefinition.RoleDefinitions,this.ScopeName);
        }

        public TaskCollection GetTasks()
        {
            return  Task.GetTasks(this.Application, this.ScopeName, GetTaskNames());
        }
       
        public OperationCollection GetOperations()
        {
            var operations = new OperationCollection();

            foreach (string strOperation in GetOperationNames())
            {
                operations.Add(this.Application.GetOperation(strOperation));
            }

            return operations;
        }

        public void AddOperation(string operationName)
        {
            this._azRoleDefinition.AddOperation(operationName, null);
        }

        public void RemoveOperation(string operationName)
        {
            this._azRoleDefinition.DeleteOperation(operationName, null);
        }

        public void RemoveTask(string childTaskName)
        {
            this._azRoleDefinition.DeleteTask(childTaskName, null);
        }

        public void AddTask(string childTaskName)
        {
            this._azRoleDefinition.AddTask(childTaskName, null);
        }

         /// <summary>
         /// Submits the updates
         /// </summary>
         public void Save()
         {
             if (_azRoleDefinition == null) return;
             this._azRoleDefinition.Name = this.Name;
             this._azRoleDefinition.Description = this.Description;
             this._azRoleDefinition.Submit(0, null);
             AuthorizationSynchronizeManager.SynchronizeManager().UpdateCache();
         }

         /// <summary>
         ///  Abort the updates
         /// </summary>
         public void Abort()
         {
             if (_azRoleDefinition == null) return;
             this._azRoleDefinition.Submit((int)tagAZ_PROP_CONSTANTS.AZ_SUBMIT_FLAG_ABORT,
                                          null);
             this.Name = this._azRoleDefinition.Name;
             this.Description = this._azRoleDefinition.Description;
             AuthorizationSynchronizeManager.SynchronizeManager().UpdateCache();
         }
       
    }
}
